﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using GeoFramework;
using GeoFramework.Gps;
using LetsDoIt.Forms;
using LetsDoIt.Interfaces;
using LetsDoIt.Common;
using LetsDoIt.Localization;
using LetsDoIt.Utils;
using LocalizedForm=LetsDoIt.Localization.LocalizedForm;

namespace LetsDoIt
{
    public partial class MainForm : LocalizedForm
	{

        public Position CurrentPosition{get; set;}
		public DilutionOfPrecision CurrentPrecision{get;set;}

		Dictionary<string, UserControl> navList = new Dictionary<string, UserControl>();
		Stack<string> navStack = new Stack<string>();

		private IntroForm frmIntro;
		private CaseForm frmCaseForm;
		private GpsSelectForm frmGpsSelectForm;
		private PhotosForm frmPhotoForm;
		private ViewCasesForm frmViewCases;
		private UserInfoForm frmUserInfo;
		private UploadCasesForm frmUploadCases;
		private MapCaseForm frmCaseMap;
        private AboutForm frmAbout;
        private SettingsForm frmSettings;

		private Settings settings = new Settings();
		public Settings Settings
		{
			get { return settings; }
			set { settings = value; }
		}
		
		public void NavigateBack(object sender, string response)
		{
			//
			if (navStack.Count > 0)
			{
				string previousNavForm = navStack.Pop();
				previousNavForm = navStack.Peek();
				NavigateToFormIdentity(this, previousNavForm);
			}
		}

		public void NavigateTo(object sender, string formIdentity)
		{
			navStack.Push(formIdentity);
			//fill the nav stack
			bool wasNavigate = NavigateToFormIdentity(sender, formIdentity);
			if(!wasNavigate)
			{
				navStack.Pop();
			}
		}

		private bool NavigateToFormIdentity(object sender, string formIdentity)
		{
			bool wasNavigate = false;
			foreach (KeyValuePair<string, UserControl> pair in navList)
			{
				if (pair.Key == formIdentity)
				{
					if (panelNavigate.Controls.Count>0)
					{
						foreach (INavigationForm navForm in panelNavigate.Controls)
						{
							navForm.NavigationLeave();
						    navForm.IsActive = false;
						}
					}
					//
					panelNavigate.Controls.Clear();
					panelNavigate.Controls.Add(pair.Value);
					pair.Value.Dock = DockStyle.Fill;
                    this.UpdateResources();
                    ((INavigationForm)pair.Value).IsActive = true;
                    ((INavigationForm)pair.Value).NavigationEnter(sender);
					pair.Value.Show();
					Application.DoEvents();
					wasNavigate = true;
				}
			}
			return wasNavigate;
		}


		public MainForm()
		{
			InitializeComponent();

			panelNavigate.Height = this.Height;
			LoadSettings();

		    this.AddMenusToDictionary();

			frmIntro = new IntroForm(this, NavigationForms.FORM_INTRO);
			frmCaseForm = new CaseForm(this, NavigationForms.FORM_CASE);
			frmGpsSelectForm = new GpsSelectForm(this, NavigationForms.FORM_GPS_SELECT);
			frmPhotoForm = new PhotosForm(this, NavigationForms.FORM_PHOTOS);
			frmViewCases = new ViewCasesForm(this, NavigationForms.FORM_VIEW_CASES);
			frmUserInfo = new UserInfoForm(this, NavigationForms.FORM_USER_INFO);
			frmUploadCases = new UploadCasesForm(this, NavigationForms.FORM_UPLOAD_CASES);
			frmCaseMap = new MapCaseForm(this, NavigationForms.FORM_CASE_MAP);
            frmAbout = new AboutForm(this, NavigationForms.FORM_ABOUT);
            frmSettings = new SettingsForm(this, NavigationForms.FORM_SETTINGS);

			AddNavigationForm(frmIntro);
			AddNavigationForm(frmCaseForm);
			AddNavigationForm(frmGpsSelectForm);
			AddNavigationForm(frmPhotoForm);
			AddNavigationForm(frmViewCases);
			AddNavigationForm(frmUserInfo);
			AddNavigationForm(frmUploadCases);
			AddNavigationForm(frmCaseMap);
            AddNavigationForm(frmAbout);
            AddNavigationForm(frmSettings);

            //set language
            if (!string.IsNullOrEmpty(Settings.Language))
                ResourceManager.Instance.Culture = new System.Globalization.CultureInfo(Settings.Language);
            this.UpdateResources();

			NavigateTo(this, NavigationForms.FORM_INTRO);
            //
            UpdateUseGpsMenu();

		}

        protected override void AddMenusToDictionary()
        {
            // this is necessary because the menu items do not
            // derive from Control and have no Name property or
            // any other way to uniquely identify them at runtime
            //
            // the fact that these string values happen to match
            // the initial display text of the menus is incidental
            // and is not necessary for the localization functionality
            // to perform as expected
            this.AddMenuToDictionary(this.menuItem1, "MainMenuFile");
            this.AddMenuToDictionary(this.mnuExit, "MainMenuExit");
            this.AddMenuToDictionary(this.mnuSelectGPS, "MainMenuSelectGps");
            this.AddMenuToDictionary(this.mnuUserInfo, "MainMenuUserInfo");
            this.AddMenuToDictionary(this.mnuViewCases, "MainMenuViewCases");
            this.AddMenuToDictionary(this.mnuAbout, "MainMenuAbout");
            this.AddMenuToDictionary(this.mnuSettings, "MainMenuSettings");
            this.AddMenuToDictionary(this.mnuUseGPSDevice, "MainMenuUseGPSDevice");
        }

		public void AddNavigationForm(INavigationForm form)
		{
			if (!navList.ContainsKey(form.Identity))
			{
				navList.Add(form.Identity, (UserControl)form);
			}
			else
			{
				MessageBox.Show(string.Format("The form key '{0}' is already in use!", form.Identity), 
					"Error", 
					MessageBoxButtons.OK, 
					MessageBoxIcon.Exclamation,
					MessageBoxDefaultButton.Button1);
			}
		}

		public INavigationForm GetFormByIdentity(string identity)
		{
			if(navList.ContainsKey(identity))
			{
				return (INavigationForm)navList[identity];
			}
			else
			{
				MessageBox.Show(string.Format("No form with key '{0}' has been defined!", identity),
					"Error",
					MessageBoxButtons.OK,
					MessageBoxIcon.Exclamation,
					MessageBoxDefaultButton.Button1);
			}
			return null;
		}

		private void LoadSettings()
		{
			Settings loadSettings = SettingsFactory.LoadSettings();
			if(loadSettings!=null)
			{
				settings = loadSettings;
			}
		}

		public void InitGpsConnection()
		{
            frmIntro.TryGpsConnect();
		}

        public void CloseGpsConnection()
        {
            frmIntro.CloseGpsConnection();
        }

		private void inputPanel1_EnabledChanged(object sender, EventArgs e)
		{
			//inputPanel1.VisibleDesktop.Height;
			if (inputPanel1.Enabled)
			{
				panelNavigate.Height = this.Height - inputPanel1.Bounds.Height;
				panelNavigate.AutoScroll = true;
				//panelNavigate.Width = this.Width - 30;
				//panelInput.Height = Screen.PrimaryScreen.WorkingArea.Height - inputPanel1.VisibleDesktop.Height;
			}
			else
			{
				panelNavigate.Height = this.Height;
				panelNavigate.AutoScroll = false;
				//panelNavigate.Width = this.Width;
				//panelInput.Height = 0;
			}
		}

		

        #region mainmenu

        private void mnuExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void mnuSelectGPS_Click(object sender, EventArgs e)
        {
            this.NavigateTo(this, NavigationForms.FORM_GPS_SELECT);
        }

        private void mnuViewCases_Click(object sender, EventArgs e)
        {
            NavigateTo(this, NavigationForms.FORM_VIEW_CASES);
        }

        private void mnuUserInfo_Click(object sender, EventArgs e)
        {
            NavigateTo(this, NavigationForms.FORM_USER_INFO);
        }

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            NavigateTo(this, NavigationForms.FORM_ABOUT);
        }

        private void mnuSettings_Click(object sender, EventArgs e)
        {
            NavigateTo(this, NavigationForms.FORM_SETTINGS);
        }

        private void mnuUseGPSDevice_Click(object sender, EventArgs e)
        {
            this.Settings.UseGps = !this.Settings.UseGps;
            SettingsFactory.SaveSettings(this.Settings);
            //update menu check
            UpdateUseGpsMenu();
        }

        #endregion mainmenu


        private void UpdateUseGpsMenu()
        {
            mnuUseGPSDevice.Checked = this.Settings.UseGps;
            if (this.Settings.UseGps)
            {
                InitGpsConnection();
            }
            else
            {
                CloseGpsConnection();
            }
        }

        private bool isMnuSelectGPS;
        private bool isMnuSettings;
        private bool isMnuUseGPSDevice;
        private bool isMnuUserInfo ;
        private bool isMnuViewCases ;
        public void SuspendMenu()
        {
            isMnuSelectGPS = mnuSelectGPS.Enabled;
            isMnuSettings = mnuSettings.Enabled;
            isMnuUseGPSDevice = mnuUseGPSDevice.Enabled;
            isMnuUserInfo = mnuUserInfo.Enabled;
            isMnuViewCases = mnuViewCases.Enabled;
        }

        public void ResumeMenu()
        {
            mnuSelectGPS.Enabled = isMnuSelectGPS;
            mnuSettings.Enabled = isMnuSettings;
            mnuUseGPSDevice.Enabled = isMnuUseGPSDevice;
            mnuUserInfo.Enabled = isMnuUserInfo;
            mnuViewCases.Enabled = isMnuViewCases;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            Unmanaged.PowerPolicyNotify(Unmanaged.PPN_UNATTENDEDMODE, 1);
        }

        private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Unmanaged.PowerPolicyNotify(Unmanaged.PPN_UNATTENDEDMODE, 0);
        }
	}
}